#ifndef GLOBAL
#define GLOBAL

#include <stdlib.h>
#include <string>
#include <stdio.h>

#include <QObject>
#include <QFile>
#include <QTextStream>
// QTextCodec 在 Qt6 中已移除，使用 QStringConverter 或其他字符串编码方式
#include <QMessageBox>
#include <QAbstractButton>
#include <QCoreApplication>
#include <QFileDialog>
#include <QTime>
#include <QProcess>
#include <QDir>
#include <QApplication>
#include <QStyleFactory>
#include <QInputDialog>
#include <QHostAddress>
#include <QNetworkInterface>
#include <QHostInfo>
#include <QStyle>
#include <QDateTime>
#include <QDebug>
#include <QStyleFactory>
#include <QSettings>

#include <QPainter>
#include <QBitmap>
#include <QPixmap>

// Qt6 新增或替代的头文件
#include <QScreen> // 替代 QDesktopWidget 用于获取屏幕信息 :cite[2]:cite[8]
#include <QGuiApplication> // 包含 QScreen 所需的 QGuiApplication
#include <QRegularExpression> // 替代 QRegExp :cite[4]

#include "myapp.h"
#include "unit.h"

// QSound 在 Qt6 中位于 QtMultimedia 模块
#include <QSoundEffect>
#include <QMediaPlayer>
#include <QAudioOutput>

class myHelper : public QObject {

public:
    //设置为开机启动
    static void AutoRunWithSystem(bool IsAutoRun, QString AppName)
    {
        QString AppPath = QApplication::applicationFilePath();
        AppPath = AppPath.replace("/","\\");

        QSettings *reg=new QSettings(
            "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
            QSettings::NativeFormat);

        if (IsAutoRun){reg->setValue(AppName,AppPath);}
        else{reg->setValue(AppName,"");}
    }

    //设置编码为UTF8 - Qt6 中 QTextCodec 已移除，此函数功能需重构或移除
    static void SetUTF8Code()
    {
        // Qt6 移除了 QTextCodec，默认字符串处理通常已足够，或使用 QStringConverter
        // 如果确实需要处理编码转换，请查阅 Qt6 文档关于 QString 和 QStringConverter 的部分
        qDebug() << "SetUTF8Code is deprecated in Qt6. Please use QString's built-in encoding support.";
    }

    //窗体居中，并且只有关闭按钮，不能调整大小
    static void FormOnlyCloseInCenter(QWidget *frm)
    {
        //设置窗体居中 - 使用 QScreen :cite[2]:cite[8]
        QScreen *primaryScreen = QGuiApplication::primaryScreen();
        if (!primaryScreen) {
            qWarning() << "Could not get primary screen";
            return;
        }
        QRect availableGeometry = primaryScreen->availableGeometry();
        int screenX = availableGeometry.width();
        int screenY = availableGeometry.height() - 40; // 可能仍需调整任务栏高度
        int frmX = frm->width();
        int frmY = frm->height();
        QPoint movePoint(screenX/2 - frmX/2, screenY/2 - frmY/2);
        frm->move(movePoint);

        //设置窗体不能调整大小
        frm->setFixedSize(frmX, frmY);

        //设置窗体只有关闭按钮
        frm->setWindowFlags(Qt::WindowCloseButtonHint);
    }

    //窗体居中显示
    static void FormInCenter(QWidget *frm)
    {
        // 使用 QScreen :cite[2]:cite[8]
        QScreen *primaryScreen = QGuiApplication::primaryScreen();
        if (!primaryScreen) {
            qWarning() << "Could not get primary screen";
            return;
        }
        QRect availableGeometry = primaryScreen->availableGeometry();
        int screenX = availableGeometry.width();
        int screenY = availableGeometry.height() - 60; // 可能仍需调整任务栏高度
        int wndX = frm->width();
        int wndY = frm->height();
        QPoint movePoint((screenX - wndX) / 2-200, (screenY - wndY) / 2-200);
        frm->move(movePoint);
    }

    //窗体没有最大化按钮
    static void FormNoMaxButton(QWidget *frm)
    {
        frm->setWindowFlags(Qt::WindowMinimizeButtonHint);
    }

    //窗体只有关闭按钮
    static void FormOnlyCloseButton(QWidget *frm)
    {
        frm->setWindowFlags(Qt::WindowCloseButtonHint);
    }

    //窗体不能改变大小
    static void FormNotResize(QWidget *frm)
    {
        frm->setFixedSize(frm->width(), frm->height());
    }

    // 设置样式
    static void setStyle(const QString &style) {
        QFile file(":/qss/resource/qss/" + style + ".css");
        if (file.open(QIODevice::ReadOnly)) {
            qApp->setStyleSheet(file.readAll());
            file.close();
        } else {
            qWarning() << "Could not open stylesheet file:" << file.fileName();
        }
    }

    //延时
    static void Sleep(int sec)
    {
        QTime dieTime = QTime::currentTime().addMSecs(sec);
        while( QTime::currentTime() < dieTime )
            QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }

    //判断是否是IP地址 - 使用 QRegularExpression 替代 QRegExp :cite[4]
    static bool IsIP(QString IP)
    {
        QRegularExpression regExp("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
        return regExp.match(IP).hasMatch();
    }

    // 获取本机ip地址
    static QString GetIP()
    {
        QList<QHostAddress> list = QNetworkInterface::allAddresses();
        foreach (QHostAddress address, list)
        {
            // 我们使用IPv4地址
            if(address.protocol() == QAbstractSocket::IPv4Protocol)
                return address.toString();
        }
        return "";
    }

    // 获取文件的大小
    static QString GetFileSize(const QString &name) {
        QFileInfo fileInfo(MyApp::m_strRecvPath + name);
        return CalcSize(fileInfo.size());
    }

    //获取选择的文件
    static QString GetFileName(QString filter)
    {
        return QFileDialog::getOpenFileName(nullptr, "选择文件", QCoreApplication::applicationDirPath(), filter);
    }

    //获取选择的文件集合
    static QStringList GetFileNames(QString filter)
    {
        return QFileDialog::getOpenFileNames(nullptr, "选择文件", QCoreApplication::applicationDirPath(), filter);
    }

    //获取选择的目录
    static QString GetFolderName()
    {
        return QFileDialog::getExistingDirectory(nullptr, "选择目录");
    }

    //获取文件名，含拓展名
    static QString GetFileNameWithExtension(QString strFilePath)
    {
        QFileInfo fileInfo(strFilePath);
        return fileInfo.fileName();
    }

    //获取选择文件夹中的文件
    static QStringList GetFolderFileNames(QStringList filter)
    {
        QStringList fileList;
        QString strFolder = QFileDialog::getExistingDirectory(nullptr, "选择目录");
        if (!strFolder.isEmpty())
        {
            QDir myFolder(strFolder);

            if (myFolder.exists())
            {
                fileList = myFolder.entryList(filter);
            }
        }
        return fileList;
    }

    //文件夹是否存在
    static bool FolderIsExist(QString strFolder)
    {
        QDir tempFolder(strFolder);
        return tempFolder.exists();
    }

    //文件是否存在
    static bool FileIsExist(QString strFile)
    {
        QFile tempFile(strFile);
        return tempFile.exists();
    }

    // 删除目录下的所有文件，包括子目录
    static void CleanDirPath(QString strPath) {
        QDir dir(strPath);
        foreach (QFileInfo mfi ,dir.entryInfoList())
        {
            if (mfi.isFile())
            {
                if (mfi.fileName().endsWith("wav")) {
                    bool bOk = QFile::remove(mfi.filePath());
                    qDebug() << "Remove Old record files:" << bOk << mfi.filePath();
                }
            }
            else
            {
                if(mfi.fileName()=="." || mfi.fileName() == "..") continue;
                CleanDirPath(mfi.absoluteFilePath());
            }
        }
    }

    // 复制文件
    static bool CopyFile(QString sourceFile, QString targetFile)
    {
        if (FileIsExist(targetFile))
        {
            int ret = QMessageBox::information(nullptr, "提示", "文件已经存在，是否替换？", QMessageBox::Yes | QMessageBox::No);
            if (ret != QMessageBox::Yes)
            {
                return false;
            }
        }
        return QFile::copy(sourceFile, targetFile);
    }

    // 播放声音 - Qt6 中 QSound 已改变，使用 QSoundEffect 或 QMediaPlayer :cite[4]
    static void PlaySound(const QString &name)
    {
        QString strSound = MyApp::m_strSoundPath + name + ".wav";
        if (!QFile::exists(strSound)) return;

        // 方式1: 使用 QSoundEffect (适合短促音效)
        /*
        QSoundEffect *effect = new QSoundEffect;
        effect->setSource(QUrl::fromLocalFile(strSound));
        effect->play();
        // 注意：需要管理 effect 对象的生命周期，例如使用 QObject::deleteLater 连接其播放完毕信号
        */

        // 方式2: 使用 QMediaPlayer (功能更强大)
        QMediaPlayer *player = new QMediaPlayer;
        QAudioOutput *audioOutput = new QAudioOutput;
        player->setAudioOutput(audioOutput);
        player->setSource(QUrl::fromLocalFile(strSound));
        player->play();
        // 连接播放完毕信号以清理资源
        QObject::connect(player, &QMediaPlayer::playbackStateChanged, [player, audioOutput](QMediaPlayer::PlaybackState state) {
            if (state == QMediaPlayer::StoppedState) {
                player->deleteLater();
                audioOutput->deleteLater();
            }
        });
    }

    // 转换html
    static void stringToHtmlFilter(QString &str)
    {
        //注意这几行代码的顺序不能乱，否则会造成多次替换
        str.replace("&", "&amp;");
        str.replace(">", "&gt;");
        str.replace("<", "&lt;");
        str.replace("\"", "&quot;");
        str.replace("\'", "&#39;");
        str.replace(" ", "&nbsp;");
        str.replace("\n", "<br>");
        str.replace("\r", "<br>");
    }

    // string 转换成html
    static void stringToHtml(QString &str, QColor crl)
    {
        QByteArray array;
        array.append(crl.red());
        array.append(crl.green());
        array.append(crl.blue());
        QString strC(array.toHex());
        str = QString("<span style=\" color:#%1;\">%2</span>").arg(strC).arg(str);
    }

    // 添加图片
    static void imgPathToHtml(QString &path)
    {
        path = QString("<img src=\"%1\"/>").arg(path);
    }

    // 添加文本
    static void stringToText(QString &str)
    {
        str = QString("<span><p>  %1</span></p>").arg(str);
    }

    static QPixmap PixmapToRound(const QPixmap &src, int radius)
    {
        if (src.isNull()) {
            return QPixmap();
        }

        QSize size(2 * radius, 2 * radius);
        QBitmap mask(size);
        QPainter painter(&mask);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setRenderHint(QPainter::SmoothPixmapTransform);
        painter.fillRect(0, 0, size.width(), size.height(), Qt::white);
        painter.setBrush(QColor(0, 0, 0));
        painter.drawRoundedRect(0, 0, size.width(), size.height(), 99, 99);

        QPixmap image = src.scaled(size);
        image.setMask(mask);
        return image;
    }

    // 灰度
    static QPixmap ChangeGrayPixmap(const QImage &image)
    {
        QImage newImage = image;
        if (newImage.isNull())
        {
            return QPixmap();
        }

        QColor oldColor;

        for(int x = 0; x < newImage.width(); x++){
            for(int y = 0; y < newImage.height(); y++){
                oldColor = QColor(newImage.pixel(x,y));
                int average = (oldColor.red() + oldColor.green() + oldColor.blue()) / 3;
                newImage.setPixel(x, y, qRgb(average, average, average));
            }
        }

        return QPixmap::fromImage(newImage);
    }

    // 文件大小转换
    static QString CalcSize(qint64 bytes)
    {
        QString strUnit;
        double dSize = bytes * 1.0;
        if (dSize <= 0)
        {
            dSize = 0.0;
        }
        else if (dSize < 1024)
        {
            strUnit = "Bytes";
        }
        else if (dSize < 1024 * 1024)
        {
            dSize /= 1024;
            strUnit = "KB";
        }
        else if (dSize < 1024 * 1024 * 1024)
        {
            dSize /= (1024 * 1024);
            strUnit = "MB";
        }
        else
        {
            dSize /= (1024 * 1024 * 1024);
            strUnit = "GB";
        }

        return QString("%1 %2").arg(QString::number(dSize, 'f', 2)).arg(strUnit);
    }

    // 计算下载速率
    static QString CalcSpeed(double speed)
    {
        QString strUnit;
        if (speed <= 0)
        {
            speed = 0;
            strUnit = "Bytes/S";
        }
        else if (speed < 1024)
        {
            strUnit = "Bytes/S";
        }
        else if (speed < 1024 * 1024)
        {
            speed /= 1024;
            strUnit = "KB/S";
        }
        else if (speed < 1024 * 1024 * 1024)
        {
            speed /= (1024 * 1024);
            strUnit = "MB/S";
        }
        else
        {
            speed /= (1024 * 1024 * 1024);
            strUnit = "GB/S";
        }

        QString strSpeed = QString::number(speed, 'f', 2);
        return QString("%1 %2").arg(strSpeed).arg(strUnit);
    }
};

#endif // GLOBAL
